<template>
  <!-- 这些属性都是父组件传递的 -->
  <el-dialog
    :title="title"
    :visible.sync="visible"
    width="500px"
    :before-close="handleClose"
  >
    <!-- v-loading="loading" 值为true 显示加载中  -->
    <el-form ref="formRef" v-loading="loading" label-width="80px">
      <!--
      :data 绑定的渲染数据，数组
      show-checkbox 显示勾选框
      node-key 树节点的唯一标识属性名
      props 配置响应数据中对应展示的属性名
      children 是子菜单的属性名 children（ 在这里定义，下面就不用定义了）
      label 展示出来的名字，我们展示菜单属性名 name（ 在这里定义，下面就不用定义了
      :default-checked-keys 默认勾选的集合(当前角色拥有的菜单-查询出来的菜单ids）
      accordion 手风琴效果，每次只能展开一个，会将之前展开把它隐藏  -->
      <el-tree
        ref="tree"
        :data="menuList"
        show-checkbox
        node-key="id"
        :props="{children: 'children', label: 'name'}"
        accordion
        :default-checked-keys="menuIds"
      />
      <el-form-item>
        <el-button v-permission="'role:permission'" type="primary" @click="submitForm('formRef')">确定</el-button>
        <el-button v-permission="'role:permission'" @click="handleClose">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>
<script>
import menuApi from '@/api/menu'
import roleApi from '@/api/role'

export default {
  // eslint-disable-next-line vue/require-prop-types
  props: ['title', 'visible', 'roleId', 'name'],
  data() {
    return {
      // true 显示加载中，false 不显示加载中
      loading: false,
      menuList: [], // 存储所有菜单
      menuIds: [] // 默认选中的角色所拥有的菜单集合
    }
  },
  watch: {
    visible(val) {
      if (val) { // 监听 visible = true 加载所有菜单
        this.getMenuList()
      }
    }
  },
  methods: {
    // 关闭窗口
    handleClose() {
      this.menuList = []
      this.menuIds = []
      this.$emit('remotePerClose')
    },
    // 获取所有菜单
    getMenuList() {
      this.loading = true // 加载中
      // 因为不需要传查询条件，所以这里给了一个空对象
      menuApi.getList({}).then(response => {
        this.menuList = response.data.menus
        // 当前角色拥有的所有菜单
        this.getMenuIdsByRoleId()
      })
      // 加载完成
      this.loading = false
    },
    // 查询当前角色之前所拥有的菜单ids，回显
    async getMenuIdsByRoleId() {
      const { data } = await roleApi.getMenuIdsByRoleId(this.roleId)
      // this.menuIds = data // 这种方法会将父节点下的所有子节点都显示
      // 循环出每个菜单id，然后打开菜单树中的节点对象 ++++
      data.menuList.forEach(id => {
        // 获取节点对象
        const node = this.$refs.tree.getNode(id) // 框架属性
        // 判断是否为子节点，如果是子节点则勾选，否则不勾选
        if (node.isLeaf) { // 框架方法 isLeaf 是否为子节点
          // 是子节点，则勾选（ 父节点没勾选 ）
          this.$refs.tree.setChecked(id, true) // 框架方法 setChecked 选中
        }
      })
    },
    // 提交表单-保存分配的菜单权限
    submitForm() {
      // 获取所有被选中的菜单id
      // ref="tree"
      const checkedMenuIds = this.$refs.tree.getCheckedKeys()
      // 获取半选中（父节点）的菜单id +++
      const parentIds = this.$refs.tree.getHalfCheckedKeys()
      // 将选中的节点和父节点的菜单id组合成一个新的数组 menuIds +++
      const menuIds = parentIds.concat(checkedMenuIds)
      // 调用保存角色权限菜单接口(将第二个参数修改为组合后的 menuIds ）+++
      roleApi.saveRoleMenu(this.roleId, menuIds).then(response => {
        if (response.code === 200) {
          this.$message.success(response.message)
          // 关闭窗口
          this.handleClose()
        } else {
          this.$message.error(response.message)
        }
      })
    }
  }
}
</script>
<style scoped>
</style>
